//
// Created by seeed on 25-8-14.
//

#include <esp32-hal.h>
#include <Wire.h>
#include "myTask.h"
#include <cstdio>
#include "global/GData.h"
#include "global/GObject.h"
#include "../../resource/bmp.h"
#include "data/dataDeal.h"

// 任务句柄
TaskHandle_t LED_Task_Handle = NULL;    // LED任务
TaskHandle_t Button_Task_Handle = NULL; // 按键检测任务
TaskHandle_t OLED_Task_Handle = NULL;   // OLED显示任务
TaskHandle_t Speak_Task_Handle = NULL;  // 通知任务
TaskHandle_t Communication_Task_Handle = NULL; // 通讯任务

// LED任务
[[noreturn]] void LED_Task_Func(void *pvParameters) {
    printf("LED_Task start running...\n");
    while (true) {
        led0.breathe();
    }
}

// 按钮检测任务
[[noreturn]] void Button_Task_Func(void *pvParameters) {
    printf("Button_Task start running...\n");
    uint16_t count = 0;
    while (true) {
        if (button0.isPressed()) {  // 按钮按下
            count ++;
            vTaskDelay(1000 / portTICK_PERIOD_MS);
            if (count >= 5) {
                visitors_today = 0 ; // 今日到访数
                visitors_num = 0 ;   // 总计到访数
            }
        }else{
            count=0;
        }
        vTaskDelay(100 / portTICK_PERIOD_MS);
    }
}

// OLED显示任务
[[noreturn]] void OLED_Task_Func(void *pvParameters) {
    char line0_text[32];    // 今日到访
    char line1_text[32];    // 总计到访

    printf("OLED_Task start running...\n");
//    oled0.setFont(u8g2_font_wqy14_t_gb2312);

    while (true) {
        oled0.clear();
        if(OLED_display_mode == 0) {
            sprintf(line0_text, "今日到访:%d次", visitors_today);
            sprintf(line1_text, "总计:%d次", visitors_num);

            oled0.drawChinese(10, 30, line0_text);
            oled0.drawChinese(10, 50, line1_text);

        }else{
            oled0.drawBitmap(0, 0, 16, 64, dellBmp);
        }
        oled0.update();
        vTaskDelay(200 / portTICK_PERIOD_MS);  // 延长显示时间以便观察
    }
}

// 通知任务
[[noreturn]] void Notification_Task_Func(void *pvParameters) {
    printf("Speak_Task start running...\n");
    while (true) {
        // 等待任务通知
        xTaskNotifyWait(ULONG_MAX, ULONG_MAX, NULL, portMAX_DELAY);

        // 显示模式切换
        OLED_display_mode = 1;

        relay0.on();            // 打开继电器
        speaker0.startPlay();   // 播放录音

        vTaskDelay(recoder0_play_time);

        speaker0.stopPlay();    // 停止播放录音
        relay0.off();           // 关闭继电器

        // 显示模式切换
        OLED_display_mode = 0;

    }
}

 // 通讯任务
 [[noreturn]] void Communication_Task_Func(void *pvParameters) {
    printf("Communication_Task start running...\n");
    while (true) {
        // 等待任务通知
        xTaskNotifyWait(ULONG_MAX, ULONG_MAX, NULL, portMAX_DELAY);
        printf("Communication_Task receive cmd\n");
        if(!stringCompare(bell_cmd,receiveData,bell_cmd_len)){
            printf("cmd right!");
            visitors_today ++ ; // 今日到访数+1
            visitors_num ++ ;   // 总计到访数+1
            xTaskNotify((TaskHandle_t )Speak_Task_Handle,0,eSetValueWithoutOverwrite);  // 发送任务通知
        }
    }
}

// 任务初始化
void Task_init() {
    // 创建LED任务（参数：任务函数，任务名，栈大小，参数，优先级，任务句柄）
    xTaskCreate( LED_Task_Func, "LED_Task", 2048, NULL, 1, &LED_Task_Handle );
    // 按钮检测任务
    xTaskCreate( Button_Task_Func, "Button_Task", 2048, NULL, 2, &Button_Task_Handle);
    // OLED显示任务
    xTaskCreate( OLED_Task_Func, "OLED_Task", 2048, NULL, 3, &OLED_Task_Handle);
    // 通知任务
    xTaskCreate(Notification_Task_Func, "Notification_Task", 2048, NULL, 4, &Speak_Task_Handle);
    // 通讯任务
    xTaskCreate(Communication_Task_Func, "Communication_Task", 2048, NULL, 5, &Communication_Task_Handle);
}

extern "C" void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) {
    // 禁用中断以确保输出完整
    portDISABLE_INTERRUPTS();

    Serial.printf("\n!!! 严重错误: 栈溢出 !!!\n");
    Serial.printf("任务: %s\n", pcTaskName);

    // 死循环 - 需要手动复位
    while(1) {
        delay(1000);
        Serial.println("系统挂起，请复位设备");
    }
}